package main

import (
	"github.com/jmoiron/sqlx"
)

type (
	// Schema 是整个项目的核心，以及入口。它将数据库中表信息转换成Go代码。
	schema struct {
		*sqlx.DB                   // 数据库指针。
		dBName   string            // 数据库名
		tables   []table           // 存储的是数据库中所有的表名 (并且里面的表都是小写表名)
		doTables []table           // 需要处理的(表名+表注释)列表 (并且里面的表都是小写表名)
		tagKeys  []string          // 结构体字段上的tagKey
		convert  map[string]string // SQL数据库表中列类型映射Golang结构体的字段类型
		path     string
	}
	// 数据库配置结构 Config
	database struct {
		DriverName string // SQL数据库驱动名，例如: mysql，postgres，mssql，sqlite3，oci8
		Host       string // 地址
		Port       int    // 端口
		Username   string // 用户名
		Password   string // 密码
		DBName     string // 数据库名
		FilePath   string // 这个是给sqlite3用的，例如: FilePath = "./test.db"
		Table      string // 数据库中的表
		TagKey     string // 结构体字段上的tagKey
	}
	gen struct {
		DriverName string
		DbName     string
		DSN        string
		Table      string // 数据库中的表
		TagKey     string // 结构体字段上的tagKey
	}
	config struct {
		Gen *gen
	}
)

// 表名与表注释 // "SELECT `TABLE_NAME` AS 'table_name', `TABLE_COMMENT` AS 'table_comment' FROM information_schema.tables WHERE `TABLE_SCHEMA` = ?"
type table struct {
	Index   int    `db:"index"`
	Name    string `db:"table_name"`    //原始表名
	Comment string `db:"table_comment"` //表注释
}

// 表名和表注释
type tableList struct {
	Index          int
	UpperTableName string
	TableName      string
	Comment        string
}

// 数据库中单张表单个列的所有信息 映射 Golang中单个结构体单个字段的所有信息。
type column2Filed struct {
	Index           int    `db:"index"`       // 列的编号(列在第几号，默认从1开始)
	ColumnName      string `db:"column_name"` // 列名
	ColumnType      string `db:"data_type"`   // 列的类型，例如: varchar,char,int,bigint...
	ColumnTypeUpper string // 列的类型(转换成大写)，例如: VARCHAR,CHAR,INT...
	ColumnTypeNum   string `db:"column_type"`    // 列的类型(长度)，例如: varchar(50),int(10)...
	ColumnComment   string `db:"column_comment"` // 列的注释
	ColumnDefault   string `db:"column_default"` // 列的默认值
	ColumnKey       bool   `db:"column_key"`     // 是否是主键
	IsNull          string `db:"is_nullable"`    // 是否为空
	FieldName       string // Golang结构体字段名称
	FieldType       string // Golang结构体字段类型
}

// markdown
type markDownData struct {
	TableList []*tableList
	DescList  []*markDownDataChild
}
type markDownDataChild struct {
	Index     int    // 自增
	TableName string // 表名
	Comment   string // 表备注
	List      []*column2Filed
}

// Golang结构体中单个字段的信息。
type fieldsInfo struct {
	FieldName   string // 被转换成驼峰命名的字段名，首字母大写。
	FieldOri    string // 原生字段名称(原Db)
	FieldType   string // 字段类型
	FieldTag    string // 字段tag标记(原FormatFields)
	FieldRemark string // 字段注释
	DbName      string // 数据库名
}

// 数据库表信息结构
type tableInfo struct {
	Table        string        // 原始表名
	Table2       string        // 原始表名2
	Table3       string        // 去除表前缀的结构体名
	TablePrefix  string        // 表前缀
	TableCamel   string        // 小驼峰表名
	TableComment string        // 表注释
	Fields       []*fieldsInfo // 表字段
}

// 生成实体的请求结构
type entityReq struct {
	Index        int             // 序列号
	TablePrefix  string          // 表前缀
	TableName    string          // 表名称
	TableComment string          // 表注释
	TableColumns []*column2Filed // 表中所有的列与Golang结构体字段的映射
	TagKeys      []string        // 结构体字段的TagName，例如: json，form，gorm，uri...
	Path         string          // 文件路径
	EntityPath   string          // 表实体文件的绝对路径 (例如: /Users/xx/go/src/entity/entity.go) 初始化时它的值是: ./output/ + GoDirEntity + DS + GoFileEntity
	EntityPkg    string          // 实体的包名。 初始化时它的值是 PkgEntity(即: entity)。 也就是常量 GoFileEntity 的包名(实体文件的包名)。
	SchemaPkg    string          // 模型的包名(该模型与数据库中的表一一对应，通过操作该模型来间接操作表)。 初始化时它的值是: PkgDbModels(即: model)。
	DTOPath      string          // 数据传输层(主要用来包装请求输入和响应输出)
}

type cmdEntity struct {
	No  string
	Msg string
}

// 数据库中单个表中单个列的信息。
type column struct {
	Index   int    // 列的序号，即:该列在表中的位置(1,2,3...)
	Name    string // 列名
	Type    string // 列类型，例如: varchar,char,int,bigint...
	TypeNum string // 列类型，例如: varchar(50),int(10)...
	Length  int64  // 列大小
	IsNull  string // 列是否为空，NO:不为空，YES:为空
	Comment string // 列注释(字段描述)
}
